﻿using AutoUpdate.Log;
using ScannerApp.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace ScannerApp.Common.PLC
{
  public  class ModBusTcp
    {
        private static Mutex m_Mutex = new Mutex();
        public static string Read(string write)
        {
            //判斷是否有其他function在讀寫PLC
            if (m_Mutex.WaitOne())
            {
                // ModBusWrapper Wrapper = ModBusWrapper.CreateInstance(Protocol.TCPIP);
              // ModBusTCPIPWrapper Wrapper = new ModBusTCPIPWrapper();
                //using (Socket sc =new   Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp))
                {
                 
                    if (!ModBusTCPIPWrapper.IsConnected)
                    {
                        ModBusTCPIPWrapper.Connect(ModBusTCPIPWrapper.Ipaddress, ModBusTCPIPWrapper.PortNum);
                        //Read(write);
                        //m_Mutex.ReleaseMutex();
                        //return;
                    }
                    string m_strReadBuffer = "";
                    string m_strSendWord = write;
                    string m_strHexTotal = CheckSum(m_strSendWord);
                    string m_strWriteBuffer = string.Concat(":", m_strSendWord, m_strHexTotal, "\r");

                    try
                    {
                        ModBusTCPIPWrapper.Send(m_strWriteBuffer);
                        //m_sp.WriteLine(m_strWriteBuffer);

                        try
                        {
                            m_strReadBuffer = ModBusTCPIPWrapper.Receive();
                        }
                        catch (InvalidOperationException ex)
                        {
                            m_strReadBuffer = ex.Message;
                        }


                    }
                    catch (InvalidOperationException ex)
                    {
                        Logger.Instance.WriteLog(publicclass.UserName + "[ModBus]" + ex.Message, LogType.Error, "ModBus");

                        return "Port Already in use by another application";
                    }
                    catch (System.IO.IOException ex)
                    {
                        Logger.Instance.WriteLog(publicclass.UserName + "[ModBus]" + ex.Message, LogType.Error, "ModBus");

                        return "Port is not Exist";
                    }
                    finally
                    {
                        m_Mutex.ReleaseMutex();
                    }
                    return m_strReadBuffer;
                }
            }


            return "";
        }
        public static string CheckSum(string writeUncheck)
        {
            char[] m_HexArray = new char[writeUncheck.Length];
            m_HexArray = writeUncheck.ToCharArray();
            int m_DecNum = 0, m_DecNumMSB = 0, m_DecNumLSB = 0;
            int m_DecByte, m_DecByteTotal = 0;

            bool m_bMsb = true;

            for (int i = 0; i <= m_HexArray.GetUpperBound(0); i++)
            {
                if ((m_HexArray[i] >= 48) && (m_HexArray[i] <= 57))
                {
                    m_DecNum = (m_HexArray[i] - 48);
                }
                else if ((m_HexArray[i] >= 65) & (m_HexArray[i] <= 70))
                {
                    m_DecNum = 10 + (m_HexArray[i] - 65);
                }

                if (m_bMsb)
                {
                    m_DecNumMSB = m_DecNum * 16;
                    m_bMsb = false;
                }
                else
                {
                    m_DecNumLSB = m_DecNum;
                    m_bMsb = true;
                }

                if (m_bMsb)
                {
                    m_DecByte = m_DecNumMSB + m_DecNumLSB;
                    m_DecByteTotal += m_DecByte;
                }
            }

            m_DecByteTotal = (255 - m_DecByteTotal) + 1;
            m_DecByteTotal = m_DecByteTotal & 255;

            int a, b = 0;

            string m_strHexByte = "", m_strHexTotal = "";
            double t;

            for (t = 0; m_DecByteTotal > 0; t++)
            {
                b = Convert.ToInt32(System.Math.Pow(16.0, t));
                a = m_DecByteTotal % 16;
                m_DecByteTotal /= 16;

                if (a <= 9)
                {
                    m_strHexByte = a.ToString();
                }
                else
                {
                    switch (a)
                    {
                        case 10:
                            m_strHexByte = "A";
                            break;
                        case 11:
                            m_strHexByte = "B";
                            break;
                        case 12:
                            m_strHexByte = "C";
                            break;
                        case 13:
                            m_strHexByte = "D";
                            break;
                        case 14:
                            m_strHexByte = "E";
                            break;
                        case 15:
                            m_strHexByte = "F";
                            break;
                    }
                }

                m_strHexTotal = String.Concat(m_strHexByte, m_strHexTotal);
            }

            return m_strHexTotal;
        }

    }
}
